#!/usr/bin/perl
use Cwd;
use File::Path qw(make_path);
use File::Temp;

use vars '$DB::inhibit_exit';
$DB::inhibit_exit = 0;

use strict;
use integer;

sub file_row($);
sub mtime($);
sub need($$);
sub size($);
sub update_diffs($$);

use constant {
    MAXKEEP => 60
};

my %var = ();

umask 0002;
$| = 1;

my $TMP = File::Temp->newdir();
my $wwwdir = getcwd;
my $http = "https://cygwin.com/snapshots";

our ($master, $perday);
for my $t (qw'master perday') {
    no strict qw{refs};
    open my $fd, '<', "$t.template" or die "$t.template: $!\n";
    ${$t} = join '', <$fd>;
    close $fd;
}

chdir $wwwdir or die "couldn't cd to $wwwdir - $!\n";

my @month = ('', '01', '02', '03', '04', '05', '06', '07', '08',
	     '09', '10', '11', '12');
my @perdays = ();
our $arch;
our @snaps;

$arch="x86";
$var{'arch'} = $arch;
my $dfd;
opendir $dfd, $arch;
my %bydate = ();
@snaps = ();
for (reverse sort readdir $dfd) {
    next unless /^(.*?)-(\d{8})((-src)?\.(.*?))$/o;
    push @{$bydate{$2}}, $_;
    push @{$bydate{$2}}, "x86_64/" . $_ if -f "x86_64/" . $_;
    push(@snaps, $2) if @snaps < MAXKEEP
	&& $1 eq 'cygwin' && $3 eq '-src.tar.xz'
	&& -s "x86_64/$_";
}
closedir $dfd;

for my $i (0..$#snaps) {
    update_diffs('cygwin', $i);
    my $date = $snaps[$i];
    $var{'date'} = $date;
    ($var{'longdate'} = $date) =~ s/(....)(..)(..)/$1-$month[$2]-$3/;

    my $time = mtime("$arch/cygwin1-$snaps[$i].dll.xz") || time;
    my ($ss, $mm, $hh, $mday, $m, $yr) = (gmtime($time))[0..5];
    $var{'longdate'} .= sprintf '&emsp;%02d:%02d:%02d&emsp;UTC', $hh, $mm, $ss;
    ($var{'longprev'} = $snaps[$i+1]) =~ s/(....)(..)(..)/$1-$month[$2]-$3/;
    if ($i < $#snaps) {
	$var{'prev'} = $snaps[$i+1];
	$var{'wsdfsz'} = size("$arch/cygwin-diffs-$snaps[$i+1]-$date");
    } else {
	$var{'diffs'} = '';
    }

    $var{'xfiles'}  = file_row("cygwin1-$snaps[$i].dll.xz");
    $var{'xfiles'} .= file_row("cygwin1-$snaps[$i].dbg.xz");
    $var{'xfiles'} .= file_row("cygwin-$snaps[$i].tar.xz");
    $var{'xfiles'} .= file_row("cygwin-$snaps[$i]-src.tar.xz");

    my $t;
    if ($i == $#snaps || (stat("$arch/cygwin-diffs-$snaps[$i+1]-$date"))[7] > 0) {
	$t = $perday;
    }
    0 while $t =~ s/<var ([a-z]+)>/$var{$1}/ge;
    push @perdays, $t;
}

my @tounlink = reverse sort keys %bydate;
for (my $i = MAXKEEP; $i < @tounlink; $i++) {
    unlink @{$bydate{$tounlink[$i]}};
}

$var{'perday'} = join '', reverse sort @perdays;
0 while $master =~ s/<var ([a-z]+)>/$var{$1}/ge;

open my $fd, '>', 'index.html';
print $fd $master;
chmod 0775, $fd;
close $fd;

exit 0;

sub file_row($) {
    my $f = shift;
    return "" unless -f "x86/$f" &&  -f "x86_64/$f";
    my $rv = "<tr>\n";
    $rv   .= "  <td>&emsp;&emsp;<tt>$f</tt></td>\n";
    foreach my $arch ( qw( x86 x86_64 ) ) {
	my $sz = size("$arch/$f");
	$rv .= "  <td align=right>$sz&nbsp;kiB&emsp;</td>";
	$rv .= "  <td align=left>&emsp;<a href=\"$http/$arch/$f\">download</a></td>\n";
    }
    $rv .= "</tr>\n";
    return $rv;
}

sub size($) {
    my $f = shift;
    print "No file $_[0]\n" unless -f $f;
    my $sz = int(((stat _)[7]+1023) / 1024);
    0 while $sz =~ s/(.*\d)(\d\d\d)/$1,$2/;
    return $sz;
}

sub mtime($) {
    my $f = shift;
    if ( -f $f) {
	return (stat(_))[9];
    } else {
	return 0;
    }
}

sub update_diffs($$) {
    my $base = shift;
    my $i = shift;

    my $basesnap = $snaps[$i + 1] or return;
    my $nextsnap = $snaps[$i];
    my $basesrc = "$base-$basesnap-src";
    my $nextsrc = "$base-$nextsnap-src";

    my $sf = mtime("$arch/$basesrc.tar.xz");
    my $osf = mtime("$arch/$nextsrc.tar.xz");
    my $df = mtime("$arch/$base-diffs-$basesnap-$nextsnap");

    if (!$df || $df < $sf || $df < $osf) {
	print "build $arch/$base-diffs-$basesnap-$nextsnap\n";
	my $basedir = need($basesnap, $basesrc);
	my $nextdir = need($nextsnap, $nextsrc);
	
	my $fnsnap = "$arch/$base-diffs-$basesnap-$nextsnap";
	open my $outfd, '>', $fnsnap or die "$0: couldn't open $fnsnap for output - $!\n";
	open my $difffd, '-|', "cd $TMP; exec diff -p -N -d -r -U2 $basedir $nextdir" or die "$0: diff $basedir $nextdir failed - $!\n";
	print $outfd "Differences between $basesnap and $nextsnap\n\n";
	my $keeper = 0;
	my $sawstuff = 0;
	while (<$difffd>) {
	    $keeper = !/\.snapshot-date|ChangeLog/o if /^diff /o;
	    print $outfd $_ if $keeper;
	    $sawstuff ||= $keeper;
	}
	close $difffd;
	chmod 0664, $outfd;
	close $outfd;
	unlink $fnsnap unless $sawstuff;
    }
}

sub need($$) {
    my ($snap, $txz) = @_;
    $txz = "$arch/$txz";
    if (!$::unpacked{$txz}) {
	print "unpacking $txz\n";
	$::unpacked{$txz} = 1;
	make_path("$TMP/$txz");
	system '/bin/tar', 'xf', "$txz.tar.xz", '-C', "$TMP/$txz";
    }
    return -d "$TMP/$txz/cygwin-snapshot-$snap-1" ?
	   "$txz/cygwin-snapshot-$snap-1" : $txz;
}
